package at.ac.tuwien.prog.system;

import java.io.File;
import java.io.IOException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import at.ac.tuwien.prog.command.ICommand;
import at.ac.tuwien.prog.compiler.ICompiler;
import at.ac.tuwien.prog.flash.IFlashManager;
import at.ac.tuwien.prog.memory.IMemoryManager;
import at.ac.tuwien.prog.parser.IParser;
import at.ac.tuwien.prog.view.MainWindow;
import at.ac.tuwien.prog.view.controller.FrontController;
import at.ac.tuwien.prog.view.controller.FrontEvent;
import at.ac.tuwien.prog.view.controller.FrontEventType;
import at.ac.tuwien.prog.view.controller.IFrontEventListener;

/**
 * 
 * @author christoph.pickl@student.tuwien.ac.at
 */
public class SystemImpl implements ISystem, IFrontEventListener {

	private static final Log LOG = LogFactory.getLog(SystemImpl.class);
	
	private final MainWindow mainWindow;

	private final IMemoryManager memoryManager;

	private final IFlashManager flashManager;
	
	private final ICompiler compiler;
	
	private final IParser parser;
	
	public SystemImpl(
			final MainWindow mainWindow,
			final IMemoryManager memoryManager,
			final IFlashManager flashManager,
			final ICompiler compiler,
			final FrontController frontController,
			final IParser parser
		) {
		this.mainWindow = mainWindow;
		this.memoryManager = memoryManager;
		this.flashManager = flashManager;
		this.compiler = compiler;
		this.parser = parser;
		frontController.addFrontEventListener(this);
	}

	
	public MainWindow getMainWindow() {
		return this.mainWindow;
	}
	
	public IMemoryManager getMemoryManager() {
		return this.memoryManager;
	}
	
	public IFlashManager getFlashManager() {
		return this.flashManager;
	}
	
	public IParser getParser() {
		return this.parser;
	}


	public ICompiler getCompiler() {
		return this.compiler;
	}


	public void eventDispatched(FrontEvent event) {
		LOG.info("eventDispatched(event="+event+")");
		
		final FrontEventType type = event.getType();
		if(type == FrontEventType.DUMMY) {

			// ICommand cmd = new SetConstantCommand(42, MemoryConstants.DISPLAY_DATA_START);
			/*
			final int registerValue = 734234232;
			ICommand cmd = CommandBitUtil.newCommandByRegister(registerValue);
			cmd.execute(memory);
			*/
			
			// Software sw = new DummySoftware();
			/*
			final IParser parser = new ParserImpl();
			final String code = "setc 7 "+(MemoryConstants.DISPLAY_DATA_START+32);
			Software sw = parser.parseText(code);
			for (ICommand cmd : sw.getCommands()) {
				cmd.execute(system);
			}
			*/
			
			final File file = new File("src/main/resources/software/dummy.txt");
			try {
				for (ICommand cmd : this.parser.parseFile(file).getCommands()) {
					cmd.execute(this);
				}
			} catch (IOException e) {
				throw new RuntimeException("Parse Error!", e);
			}
		} else if(type == FrontEventType.QUIT) {
			this.mainWindow.dispose();
			
		} else {
			throw new RuntimeException("Unhandled type: " + type);
		}
	}
}
